package dcutils.sock;

// Import Java JDK Classes
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;

/**
 * A commandline which runs in a thread so it doesn't block the main program.
 * @author dca
 */
public class AsyncCmdLine extends AsyncInput {
   private Connection connection; // A single client connection
   private List<Connection> connections; // Multiple server connections
   private List<String> breakStrings; // A list of strings used to end the command line loop

   public AsyncCmdLine(Connection connection, List<String> breakStrings) {
      this.connection = connection;
      this.breakStrings = breakStrings;
      this.active = true;
      new Thread(this, AsyncCmdLine.class.getSimpleName()).start();
   } // END constructor

   public AsyncCmdLine(List<Connection> connections, List<String> breakStrings) {
      this.connections = connections;
      this.breakStrings = breakStrings;
      this.active = true;
      new Thread(this).start();
   } // END constructor

   @Override
   public void run() {
      String line = "";
      try(BufferedReader cmdIn = new BufferedReader(new InputStreamReader(System.in))) {
         while(this.active && (line = cmdIn.readLine()) != null) {
            // Is connection defined?
            if(null != this.connection && !this.connection.isClosed()) {
               this.connection.send(line); // Send data from command line to the connection
            } // END if

            // Are connections defined?
            if(null != this.connections) {
               for(Connection c : this.connections) { // Broadcast to all connections
                  if(null != c && !c.isClosed()) {
                     c.send(line); // Send data from command line to the connection
                  } // END if
               } // END loop
            } // END if

            if(this.breakStrings.contains(line)) break;
         } // END loop
         Thread.sleep(1000L); // wait for connection socket to receive the break string.
      } catch(Exception exc) {
         System.out.printf("Warning: %s: Could not read from command line.  Message was: %s%n", exc.getClass().getSimpleName(), exc.getMessage());
         exc.printStackTrace();
      } finally {
         // Is connection defined?
         if(null != this.connection && !this.connection.isClosed()) {
            System.out.println("Closing connection.");
            connection.closeSocket();
         } // END if

         // Are connections defined?
         if(null != this.connections) {
            System.out.println("Closing all connections.");
            for(Connection c : this.connections) {
               if(null != c && !c.isClosed()) {
                  System.out.println("Closing connection.");
                  c.closeSocket();
               } // END if
            } // END loop
         } // END if

         System.out.println("Deactivating AsyncCmdLine instance.");
         deactivate();
      } // END try/catch/finally
   } // END run
} // END class AsyncCmdLine
